Author: Gao Pengbing (nbgao)
Email: nbgao@126.com
import numpy as np
import cv2
import matplotlib.pyplot as plt
import warnings
%matplotlib inline
warnings.filterwarnings('ignore')
def blocks_reshape(blocks):
n_rows, n_cols = blocks.shape[:2]
img_reshape = None
cols = np.zeros((n_rows, 8, 256))
for i in range(n_rows):
cols[i] = np.column_stack(blocks[i,:])
img_reshape = np.row_stack(cols)
return img_reshape
def DCT(image):
if(np.ndim(image)==2):
h, w = image.shape
n_rows, n_cols = h//8, w//8
dct_mat = np.zeros((n_rows, n_cols, 8 ,8))
rows = np.vsplit(image, h/8)
for i in range(n_rows):
row = np.hsplit(rows[i], w/8)
for j in range(n_cols):
block = row[j]
dct_mat[i,j] = cv2.dct(block)
# dct_mat[i,j,abs(dct_mat[i,j])<50] = 0
# idct_mat[i,j] = np.uint8(cv2.idct(dct_mat[i,j]))
img_dct = blocks_reshape(dct_mat)
img_dct = np.log(abs(img_dct))
return img_dct, dct_mat
elif(np.ndim(image)==3):
img_list = [image[:,:,i] for i in range(3)]
h, w = image.shape[:2]
n_rows, n_cols = h//8, w//8
dct_list = [np.zeros((n_rows, n_cols, 8 ,8)) for i in range(3)]
for c in range(3):
rows = np.vsplit(img_list[c], h//8)
for i in range(n_rows):
row = np.hsplit(rows[i], w/8)
for j in range(n_cols):
block = row[j]
dct_list[c][i,j] = cv2.dct(block)
img_dct = np.zeros_like(image)
for i in range(3):
img_dct[:,:,i] = blocks_reshape(dct_list[i])
img_dct = np.log(abs(img_dct))
return img_dct, dct_list
def blocks_figure(dct_mat):
if(np.ndim(dct_mat)==4):
n_rows, n_cols = np.shape(dct_mat)[:2]
plt.figure(figsize=(6,6))
# plt.title('分块频谱图')
for i in range(n_rows):
for j in range(n_cols):
plt.subplot(n_rows, n_cols, i*n_cols+j+1)
plt.imshow(np.log(np.abs(dct_mat[i,j])), 'gray')
plt.axis('off')
plt.tight_layout(pad=0.2)
plt.show()
elif(np.ndim(dct_mat)==5):
n_rows, n_cols = np.shape(dct_mat)[1:3]
dct_new = np.array(dct_mat)
dct_mat_mean = np.mean(dct_new, axis=0)
plt.figure(figsize=(6,6))
for i in range(n_rows):
for j in range(n_cols):
plt.subplot(n_rows, n_cols, i*n_cols+j+1)
plt.imshow(np.log(np.abs(dct_mat_mean[i,j])), 'gray')
plt.axis('off')
plt.tight_layout(pad=0.2)
plt.show()
return
def IDCT(dct_mat, T=0):
# 每个分块内DCT系数绝对值小于T的置0
print('稀疏率:{:.2f}%'.format(np.sum(np.abs(dct_mat)<T)/np.size(dct_mat)*100))
if(np.ndim(dct_mat)==4): # 灰度dct分块图
n_rows, n_cols = np.shape(dct_mat)[:2]
dct_new = dct_mat.copy()
idct_mat = np.zeros_like(dct_mat)
for i in range(n_rows):
for j in range(n_cols):
dct_new[i,j,np.abs(dct_new[i,j])<T] = 0
idct_mat[i,j] = np.uint8(cv2.idct(dct_new[i,j]))
img_idct = blocks_reshape(idct_mat)
img_idct = np.uint8(img_idct)
return img_idct, idct_mat
elif(np.ndim(dct_mat)==5): # 彩色dct分块图
n_rows, n_cols = np.shape(dct_mat)[1:3]
dct_new = dct_mat.copy()
idct_mat = np.zeros_like(dct_mat)
for c in range(3):
for i in range(n_rows):
for j in range(n_cols):
dct_new[c][i,j,np.abs(dct_new[c][i,j])<T] = 0
idct_mat[c][i,j] = np.uint8(cv2.idct(dct_new[c][i,j]))
img_idct = [blocks_reshape(idct_mat[i]) for i in range(3)]
img_idct = np.uint8(cv2.merge(img_idct))
return img_idct, idct_mat
def image_figure(img1, img2):
if(np.ndim(img1)==2):
plt.figure(figsize=(10, 5))
plt.subplot(121)
plt.imshow(img1, 'gray')
plt.title('Original')
plt.axis('off')
plt.subplot(122)
plt.imshow(img2, 'gray')
plt.title('IDCT')
plt.axis('off')
plt.show()
elif(np.ndim(img1)==3):
plt.figure(figsize=(10, 5))
plt.subplot(121)
plt.imshow(img1)
plt.title('Original')
plt.axis('off')
plt.subplot(122)
plt.imshow(img2)
plt.title('IDCT')
plt.axis('off')
plt.show()
for i in range(1,6):
file_path = '../Image/image'+str(i)+'.jpg'
img_bgr = cv2.imread(file_path)
img_bgr = cv2.resize(img_bgr, (256,256))
img_bgr = np.float32(img_bgr)
img_rgb = cv2.cvtColor(img_bgr, cv2.COLOR_BGR2RGB)
img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_RGB2GRAY)
print('Image{}:'.format(i), img_rgb.shape)
# 灰度图 DCT IDCT
img_gray_dct, dct_mat_gray = DCT(img_gray)
blocks_figure(dct_mat_gray)
img_gray_idct, idct_mat_gray = IDCT(dct_mat_gray, 50)
image_figure(img_gray, img_gray_idct)
# 彩色图 FFT IFFT
img_rgb_dct, dct_mat_rgb = DCT(img_rgb)
blocks_figure(dct_mat_rgb)
img_rgb_idct, idct_mat_rgb = IDCT(dct_mat_rgb, 50)
image_figure(np.uint8(img_rgb), img_rgb_idct)